package com.lostreseditores.sabersai.model.control;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.lostreseditores.sabersai.dataaccess.daoFactory.XMLHibernateDaoFactory;
import com.lostreseditores.sabersai.dataaccess.sessionFactory.HibernateSessionFactory;
import com.lostreseditores.sabersai.exceptions.ZMessManager;
import com.lostreseditores.sabersai.model.Bases;
import com.lostreseditores.sabersai.model.Examen;
import com.lostreseditores.sabersai.model.dto.BasesDTO;
import com.lostreseditores.sabersai.utilities.Utilities;


public class BasesLogic implements IBasesLogic {
    public List<Bases> getBases() throws Exception {
        List<Bases> list = new ArrayList<Bases>();

        try {
            list = XMLHibernateDaoFactory.getInstance().getBasesDAO().findAll();
        } catch (Exception e) {
            throw new ZMessManager().new GettingException(ZMessManager.ALL +
                "Bases");
        } finally {
        }

        return list;
    }

    public void saveBases(Integer baseidn, Long bcompetenciafinn,
        Long bcompetenciainin, Long bcomponentefinn, Long bcomponenteinin,
        String bdescripcionv, Long bdiferencian, Long bpromediofinn,
        Long bpromedioinin, Long btotalfinn, Long btotalinin)
        throws Exception {
        Bases entity = null;

        try {
            if (baseidn == null) {
                throw new ZMessManager().new EmptyFieldException("baseidn");
            }

            if ((bcompetenciafinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcompetenciafinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcompetenciafinn");
            }

            if ((bcompetenciainin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcompetenciainin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcompetenciainin");
            }

            if ((bcomponentefinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcomponentefinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcomponentefinn");
            }

            if ((bcomponenteinin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcomponenteinin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcomponenteinin");
            }

            if ((bdescripcionv != null) &&
                    (Utilities.checkWordAndCheckWithlength(bdescripcionv, 80) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bdescripcionv");
            }

            if ((bdiferencian != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bdiferencian, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bdiferencian");
            }

            if ((bpromediofinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bpromediofinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bpromediofinn");
            }

            if ((bpromedioinin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bpromedioinin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bpromedioinin");
            }

            if ((btotalfinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        btotalfinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "btotalfinn");
            }

            if ((btotalinin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        btotalinin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "btotalinin");
            }

            entity = getBases(baseidn);

            if (entity != null) {
                throw new ZMessManager(ZMessManager.ENTITY_WITHSAMEKEY);
            }

            entity = new Bases();
            entity.setBaseidn(baseidn);
            entity.setBcompetenciafinn(bcompetenciafinn);
            entity.setBcompetenciainin(bcompetenciainin);
            entity.setBcomponentefinn(bcomponentefinn);
            entity.setBcomponenteinin(bcomponenteinin);
            entity.setBdescripcionv(bdescripcionv);
            entity.setBdiferencian(bdiferencian);
            entity.setBpromediofinn(bpromediofinn);
            entity.setBpromedioinin(bpromedioinin);
            entity.setBtotalfinn(btotalfinn);
            entity.setBtotalinin(btotalinin);
            HibernateSessionFactory.beginTransaction();
            XMLHibernateDaoFactory.getInstance().getBasesDAO().save(entity);
            HibernateSessionFactory.commit();
        } catch (Exception e) {
            HibernateSessionFactory.rollback();
            throw e;
        } finally {
            HibernateSessionFactory.closeSession();
        }
    }

    public void deleteBases(Integer baseidn) throws Exception {
        Bases entity = null;

        if (baseidn == null) {
            throw new ZMessManager().new EmptyFieldException("baseidn");
        }

        List<Examen> examens = null;
        entity = getBases(baseidn);

        if (entity == null) {
            throw new ZMessManager().new EmptyFieldException("Bases");
        }

        try {
            examens = XMLHibernateDaoFactory.getInstance().getExamenDAO()
                                            .findByProperty("bases.baseidn",
                    baseidn);

            if (Utilities.validationsList(examens) == true) {
                throw new ZMessManager().new DeletingException("examens");
            }

            HibernateSessionFactory.beginTransaction();
            XMLHibernateDaoFactory.getInstance().getBasesDAO().delete(entity);
            HibernateSessionFactory.commit();
        } catch (Exception e) {
            HibernateSessionFactory.rollback();
            throw e;
        } finally {
            HibernateSessionFactory.closeSession();
        }
    }

    public void updateBases(Integer baseidn, Long bcompetenciafinn,
        Long bcompetenciainin, Long bcomponentefinn, Long bcomponenteinin,
        String bdescripcionv, Long bdiferencian, Long bpromediofinn,
        Long bpromedioinin, Long btotalfinn, Long btotalinin)
        throws Exception {
        Bases entity = null;

        try {
            if (baseidn == null) {
                throw new ZMessManager().new EmptyFieldException("baseidn");
            }

            if ((bcompetenciafinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcompetenciafinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcompetenciafinn");
            }

            if ((bcompetenciainin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcompetenciainin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcompetenciainin");
            }

            if ((bcomponentefinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcomponentefinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcomponentefinn");
            }

            if ((bcomponenteinin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bcomponenteinin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bcomponenteinin");
            }

            if ((bdescripcionv != null) &&
                    (Utilities.checkWordAndCheckWithlength(bdescripcionv, 80) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bdescripcionv");
            }

            if ((bdiferencian != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bdiferencian, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bdiferencian");
            }

            if ((bpromediofinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bpromediofinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bpromediofinn");
            }

            if ((bpromedioinin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        bpromedioinin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "bpromedioinin");
            }

            if ((btotalfinn != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        btotalfinn, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "btotalfinn");
            }

            if ((btotalinin != null) &&
                    (Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
                        btotalinin, 131089, 0) == false)) {
                throw new ZMessManager().new NotValidFormatException(
                    "btotalinin");
            }

            entity = getBases(baseidn);

            if (entity == null) {
                throw new ZMessManager(ZMessManager.ENTITY_NOENTITYTOUPDATE);
            }

            entity.setBaseidn(baseidn);
            entity.setBcompetenciafinn(bcompetenciafinn);
            entity.setBcompetenciainin(bcompetenciainin);
            entity.setBcomponentefinn(bcomponentefinn);
            entity.setBcomponenteinin(bcomponenteinin);
            entity.setBdescripcionv(bdescripcionv);
            entity.setBdiferencian(bdiferencian);
            entity.setBpromediofinn(bpromediofinn);
            entity.setBpromedioinin(bpromedioinin);
            entity.setBtotalfinn(btotalfinn);
            entity.setBtotalinin(btotalinin);
            HibernateSessionFactory.beginTransaction();
            XMLHibernateDaoFactory.getInstance().getBasesDAO().update(entity);
            HibernateSessionFactory.commit();
        } catch (Exception e) {
            HibernateSessionFactory.rollback();
            throw e;
        } finally {
            HibernateSessionFactory.closeSession();
        }
    }

    public Bases getBases(Integer baseidn) throws Exception {
        Bases entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance().getBasesDAO()
                                           .findById(baseidn);
        } catch (Exception e) {
            throw new ZMessManager().new FindingException("Bases");
        } finally {
        }

        return entity;
    }

    public List<BasesDTO> getDataBases() throws Exception {
        try {
            List<Bases> bases = XMLHibernateDaoFactory.getInstance()
                                                      .getBasesDAO().findAll();

            List<BasesDTO> basesDTO = new ArrayList<BasesDTO>();

            for (Bases basesTmp : bases) {
                BasesDTO basesDTO2 = new BasesDTO();

                basesDTO2.setBaseidn(basesTmp.getBaseidn());
                basesDTO2.setBcompetenciafinn((basesTmp.getBcompetenciafinn() != null)
                    ? basesTmp.getBcompetenciafinn() : null);
                basesDTO2.setBcompetenciainin((basesTmp.getBcompetenciainin() != null)
                    ? basesTmp.getBcompetenciainin() : null);
                basesDTO2.setBcomponentefinn((basesTmp.getBcomponentefinn() != null)
                    ? basesTmp.getBcomponentefinn() : null);
                basesDTO2.setBcomponenteinin((basesTmp.getBcomponenteinin() != null)
                    ? basesTmp.getBcomponenteinin() : null);
                basesDTO2.setBdescripcionv((basesTmp.getBdescripcionv() != null)
                    ? basesTmp.getBdescripcionv() : null);
                basesDTO2.setBdiferencian((basesTmp.getBdiferencian() != null)
                    ? basesTmp.getBdiferencian() : null);
                basesDTO2.setBpromediofinn((basesTmp.getBpromediofinn() != null)
                    ? basesTmp.getBpromediofinn() : null);
                basesDTO2.setBpromedioinin((basesTmp.getBpromedioinin() != null)
                    ? basesTmp.getBpromedioinin() : null);
                basesDTO2.setBtotalfinn((basesTmp.getBtotalfinn() != null)
                    ? basesTmp.getBtotalfinn() : null);
                basesDTO2.setBtotalinin((basesTmp.getBtotalinin() != null)
                    ? basesTmp.getBtotalinin() : null);
                basesDTO.add(basesDTO2);
            }

            return basesDTO;
        } catch (Exception e) {
            throw e;
        }
    }

    public List<Bases> findPageBases(String sortColumnName,
        boolean sortAscending, int startRow, int maxResults)
        throws Exception {
        List<Bases> entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance().getBasesDAO()
                                           .findPageBases(sortColumnName,
                    sortAscending, startRow, maxResults);
        } catch (Exception e) {
            throw new ZMessManager().new FindingException("Bases");
        } finally {
        }

        return entity;
    }

    public Long findTotalNumberBases() throws Exception {
        Long entity = null;

        try {
            entity = XMLHibernateDaoFactory.getInstance().getBasesDAO()
                                           .findTotalNumberBases();
        } catch (Exception e) {
            throw new ZMessManager().new FindingException("Bases Count");
        } finally {
        }

        return entity;
    }

    /**
    *
    * @param varibles
    *            este arreglo debera tener:
    *
    * [0] = String variable = (String) varibles[i]; representa como se llama la
    * variable en el pojo
    *
    * [1] = Boolean booVariable = (Boolean) varibles[i + 1]; representa si el
    * valor necesita o no ''(comillas simples)usado para campos de tipo string
    *
    * [2] = Object value = varibles[i + 2]; representa el valor que se va a
    * buscar en la BD
    *
    * [3] = String comparator = (String) varibles[i + 3]; representa que tipo
    * de busqueda voy a hacer.., ejemplo: where nombre=william o where nombre<>william,
        * en este campo iria el tipo de comparador que quiero si es = o <>
            *
            * Se itera de 4 en 4..., entonces 4 registros del arreglo representan 1
            * busqueda en un campo, si se ponen mas pues el continuara buscando en lo
            * que se le ingresen en los otros 4
            *
            *
            * @param variablesBetween
            *
            * la diferencia son estas dos posiciones
            *
            * [0] = String variable = (String) varibles[j]; la variable ne la BD que va
            * a ser buscada en un rango
            *
            * [1] = Object value = varibles[j + 1]; valor 1 para buscar en un rango
            *
            * [2] = Object value2 = varibles[j + 2]; valor 2 para buscar en un rango
            * ejempolo: a > 1 and a < 5 --> 1 seria value y 5 seria value2
                *
                * [3] = String comparator1 = (String) varibles[j + 3]; comparador 1
                * ejemplo: a comparator1 1 and a < 5
                    *
                    * [4] = String comparator2 = (String) varibles[j + 4]; comparador 2
                    * ejemplo: a comparador1>1  and a comparador2<5  (el original: a > 1 and a <
                            * 5) *
                            * @param variablesBetweenDates(en
                            *            este caso solo para mysql)
                            *  [0] = String variable = (String) varibles[k]; el nombre de la variable que hace referencia a
                            *            una fecha
                            *
                            * [1] = Object object1 = varibles[k + 2]; fecha 1 a comparar(deben ser
                            * dates)
                            *
                            * [2] = Object object2 = varibles[k + 3]; fecha 2 a comparar(deben ser
                            * dates)
                            *
                            * esto hace un between entre las dos fechas.
                            *
                            * @return lista con los objetos que se necesiten
                            * @throws Exception
                            */
    public List<Bases> findByCriteria(Object[] variables,
        Object[] variablesBetween, Object[] variablesBetweenDates)
        throws Exception {
        List<Bases> list = new ArrayList<Bases>();
        String where = new String();
        String tempWhere = new String();

        if (variables != null) {
            for (int i = 0; i < variables.length; i++) {
                if ((variables[i] != null) && (variables[i + 1] != null) &&
                        (variables[i + 2] != null) &&
                        (variables[i + 3] != null)) {
                    String variable = (String) variables[i];
                    Boolean booVariable = (Boolean) variables[i + 1];
                    Object value = variables[i + 2];
                    String comparator = (String) variables[i + 3];

                    if (booVariable.booleanValue()) {
                        tempWhere = (tempWhere.length() == 0)
                            ? ("(model." + variable + " " + comparator + " \'" +
                            value + "\' )")
                            : (tempWhere + " AND (model." + variable + " " +
                            comparator + " \'" + value + "\' )");
                    } else {
                        tempWhere = (tempWhere.length() == 0)
                            ? ("(model." + variable + " " + comparator + " " +
                            value + " )")
                            : (tempWhere + " AND (model." + variable + " " +
                            comparator + " " + value + " )");
                    }
                }

                i = i + 3;
            }
        }

        if (variablesBetween != null) {
            for (int j = 0; j < variablesBetween.length; j++) {
                if ((variablesBetween[j] != null) &&
                        (variablesBetween[j + 1] != null) &&
                        (variablesBetween[j + 2] != null) &&
                        (variablesBetween[j + 3] != null) &&
                        (variablesBetween[j + 4] != null)) {
                    String variable = (String) variablesBetween[j];
                    Object value = variablesBetween[j + 1];
                    Object value2 = variablesBetween[j + 2];
                    String comparator1 = (String) variablesBetween[j + 3];
                    String comparator2 = (String) variablesBetween[j + 4];
                    tempWhere = (tempWhere.length() == 0)
                        ? ("(" + value + " " + comparator1 + " " + variable +
                        " and " + variable + " " + comparator2 + " " + value2 +
                        " )")
                        : (tempWhere + " AND (" + value + " " + comparator1 +
                        " " + variable + " and " + variable + " " +
                        comparator2 + " " + value2 + " )");
                }

                j = j + 4;
            }
        }

        if (variablesBetweenDates != null) {
            for (int k = 0; k < variablesBetweenDates.length; k++) {
                if ((variablesBetweenDates[k] != null) &&
                        (variablesBetweenDates[k + 1] != null) &&
                        (variablesBetweenDates[k + 2] != null)) {
                    String variable = (String) variablesBetweenDates[k];
                    Object object1 = variablesBetweenDates[k + 1];
                    Object object2 = variablesBetweenDates[k + 2];
                    String value = null;
                    String value2 = null;

                    try {
                        Date date1 = (Date) object1;
                        Date date2 = (Date) object2;
                        value = Utilities.formatDateWithoutTimeInAStringForBetweenWhere(date1);
                        value2 = Utilities.formatDateWithoutTimeInAStringForBetweenWhere(date2);
                    } catch (Exception e) {
                        list = null;
                        throw e;
                    }

                    tempWhere = (tempWhere.length() == 0)
                        ? ("(model." + variable + " between \'" + value +
                        "\' and \'" + value2 + "\')")
                        : (tempWhere + " AND (model." + variable +
                        " between \'" + value + "\' and \'" + value2 + "\')");
                }

                k = k + 2;
            }
        }

        if (tempWhere.length() == 0) {
            where = null;
        } else {
            where = "(" + tempWhere + ")";
        }

        try {
            list = XMLHibernateDaoFactory.getInstance().getBasesDAO()
                                         .findByCriteria(where);
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        } finally {
        }

        return list;
    }
}
